﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Data;
using Budgetsch.Web.EntityModel;
using Budgetsch.Web.Services;
using GalaSoft.MvvmLight;

namespace Budgetsch.ViewModels.Savings
{
    public class SavingsVM : ViewModelBase
    {
        #region Private members

        private readonly BudgetschDomainContext m_context;
        private PagedCollectionView m_savings = null;
        private bool m_isBusyLoadingSavings = true;
        private bool m_isBusyLoadingComments = true;
        private bool m_isInMonthMode = true;
        private int m_selectedYear;
        private int m_selectedMonth;

        #endregion

        #region Public properties

        public const string SavingsPropertyName = "Savings";
        public const string IsBusyLoadingSavingsPropertyName = "IsBusyLoadingSavings";
        public const string IsBusyLoadingCommentsPropertyName = "IsBusyLoadingComments";

        public PagedCollectionView Savings
        {
            get
            {
                return m_savings;
            }

            set
            {
                if (m_savings == value)
                {
                    return;
                }

                m_savings = value;
                RaisePropertyChanged(() => Savings);
            }
        }

        public bool IsBusyLoadingSavings
        {
            get
            {
                return m_isBusyLoadingSavings;
            }

            set
            {
                if (m_isBusyLoadingSavings == value)
                {
                    return;
                }

                m_isBusyLoadingSavings = value;
                RaisePropertyChanged(() => IsBusyLoadingSavings);
            }
        }

        public bool IsBusyLoadingComments
        {
            get
            {
                return m_isBusyLoadingComments;
            }

            set
            {
                if (m_isBusyLoadingComments == value)
                {
                    return;
                }

                m_isBusyLoadingComments = value;
                RaisePropertyChanged(() => IsBusyLoadingComments);
            }
        }

        public AddSavingVM AddSavingVM { get; set; }

        public ObservableCollection<Tuple<SavingComment, string>> SavingComments { get; set; }

        public bool IsInMonthMode
        {
            get { return m_isInMonthMode; }
            set
            {
                m_isInMonthMode = value;
                ChangeTimeframe();
            }
        }

        public int SelectedMonth
        {
            get { return m_selectedMonth; }
            set { m_selectedMonth = value; ChangeTimeframe(); }
        }
        public int SelectedYear
        {
            get { return m_selectedYear; }
            set { m_selectedYear = value; ChangeTimeframe(); }
        }

        #endregion

        public SavingsVM()
        {
            m_context = new BudgetschDomainContext();
            m_context.Load(m_context.GetSavingsForMonthQuery(DateTime.Now.Date.Month), x =>
            {
                IsBusyLoadingSavings = false;
                Savings = new PagedCollectionView(m_context.Savings);
                Savings.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
            }, new object());
            SavingComments = new ObservableCollection<Tuple<SavingComment, string>>();
            m_context.Load(m_context.GetSavingCommentsQuery(), x =>
            {
                foreach (var c in m_context.SavingComments)
                {
                    SavingComments.Add(new Tuple<SavingComment, string>(c, string.Format("{0}@{1}", c.Saving.SavingCategory.Name, c.Saving.Date.ToShortDateString())));
                }
                IsBusyLoadingComments = false;
            }, new object());
            AddSavingVM = new AddSavingVM(m_context);
            IsInMonthMode = true;
        }

        #region Public methods

        public void GetExcelFileAsync()
        {
            m_context.InvokeOperation("GetExcelData", typeof(byte[]), null, false, x => ExcelFileReady(x.Value as byte[]), null);
        }

        public event Action<byte[]> ExcelFileReady;

        public void RemoveSaving(object o_)
        {
            var saving = o_ as Saving;
            if (saving != null)
            {
                m_context.Savings.Remove(saving);
            }
            m_context.SubmitChanges();
        }

        public AddSavingVM GetNewAddSavingVM()
        {
            var vm = new AddSavingVM(m_context);
            vm.ItemAdded += () =>
                                {
                                    IsBusyLoadingSavings = true;
                                    m_context.Load(m_context.GetSavingsForMonthQuery(DateTime.Now.Date.Month), x =>
                                    {
                                        IsBusyLoadingSavings = false;
                                        Savings = new PagedCollectionView(m_context.Savings);
                                        Savings.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                                    }, new object());

                                };
            return vm;
        }

        public EditSavingVM GetNewSavingEditorVM(object p)
        {
            var saving = p as Saving;
            if (p != null)
            {
                return new EditSavingVM(m_context, saving);
            }
            else throw new ArgumentException("Provided object must be an Saving item!");
        }

        public void AddCategory(string category_)
        {
            m_context.SavingCategories.Add(new SavingCategory() { Name = category_ });
            m_context.SubmitChanges();
        }

        public void RefreshSavings()
        {
            RaisePropertyChanged(() => Savings);
        }

        #endregion

        private void ChangeTimeframe()
        {
            IsBusyLoadingSavings = true;
            m_context.Savings.Clear();
            if (IsInMonthMode)
            {
                m_context.Load(m_context.GetSavingsForMonthQuery(SelectedMonth), x =>
                {
                    IsBusyLoadingSavings = false;
                    Savings = new PagedCollectionView(m_context.Savings);
                    Savings.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                }, new object());
            }
            else
            {
                m_context.Load(m_context.GetSavingsForYearQuery(SelectedYear), x =>
                {
                    IsBusyLoadingSavings = false;
                    Savings = new PagedCollectionView(m_context.Savings);
                    Savings.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                }, new object());
            }
        }
    }
}